import java.awt.Color;

public class Rainbow { 

    public static void main(String[] args) { 

        int N = Integer.parseInt(args[0]);
        int SIZE = 1000;
        StdDraw.setCanvasSize(SIZE, SIZE/2);
        StdDraw.setXscale(0, SIZE);
        StdDraw.setYscale(0, SIZE/2.0);
        StdDraw.enableDoubleBuffering();

        Color skyblue = new Color(48, 144, 199);
        StdDraw.clear(skyblue);

        for (int i = 0; i < N; i++) {

            double r = Math.random();
            double theta = Math.random() * 2 * Math.PI;     
            double x = Math.sqrt(r) * Math.sin(theta);
            double y = Math.sqrt(r) * Math.cos(theta);

            float c  = (float) Math.random();              
            double n = 1.33 + 0.06 * c;                     
            double thetaI = Math.asin(r);                   
            double thetaR = Math.asin(r / n);              
            double thetaP = 4*thetaR - 2*thetaI;            
            double thetaS = 6*thetaR - 2*thetaI - Math.PI;

            double p = Math.pow(Math.sin(thetaI - thetaR)
            double s = Math.pow(Math.tan(thetaI - thetaR)
            double intensityP = 0.5 * (  s*(1-s)*(1-s) +   p*(1-p)*(1-p));
            double intensityS = 0.5 * (s*s*(1-s)*(1-s) + p*p*(1-p)*(1-p));

            float saturation = (float) Math.min(intensityP / 0.04, 1.0);
            StdDraw.setPenColor(Color.getHSBColor(c, saturation, 1.0f));
            double xp = (SIZE/2.0 * thetaP * 3 / Math.PI * x / r) + SIZE / 2.0;
            double yp = (SIZE/2.0 * thetaP * 3 / Math.PI * Math.abs(y) / r);
            StdDraw.point(xp, yp);

            saturation = (float) Math.min(intensityS / 0.02, 1.0);
            StdDraw.setPenColor(Color.getHSBColor(c, saturation, 1.0f));
            double xs = ( SIZE/2.0 * thetaS * 3 / Math.PI * x / r) + SIZE / 2.0;
            double ys = (-SIZE/2.0 * thetaS * 3 / Math.PI * Math.abs(y) / r);
            StdDraw.point(xs, ys);

            if (i % 1000 == 0) {
                StdDraw.show();
                StdDraw.pause(10);
            }
        }

        StdDraw.show();
    }

}
